<?php

namespace App\Service\ChatGroup;

use App\Models\BaseModel;
use App\Models\ChatGroup\ChatGroupFAQModel;
use App\Models\ChatGroup\ChatGroupHistoryModel;
use App\Models\ChatGroup\ChatGroupSessionModel;
use App\Models\ChatGroup\ChatGroupUserModel;
use App\Service\BaseService;
use Exception;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;
use Kuafu\GreenContent\Content\TextContent;

class ChatGroupPrepareStructService extends BaseService
{
    private int    $groupId;
    private int    $shopId;
    private int    $currentUid;
    private string $clientMsgId;
    private string $type;
    private        $content;
    private int    $faqId;
    private int    $sessionId;
    private int    $isSendAi;

    public function __construct(
        int $groupId,
        int $shopId,
        int $currentUid,
        string $clientMsgId,
        string $type,
        $content,
        int $faqId = 0,
        int $sessionId = 0,
        int $isSendAi = ChatGroupHistoryModel::IS_SEND_AI_YES,
        int $isRecordStatistics = ChatGroupHistoryModel::IS_RECORD_COUNT_YES
    ) {
        $this->groupId            = $groupId;
        $this->shopId             = $shopId;
        $this->currentUid         = $currentUid;
        $this->clientMsgId        = $clientMsgId;
        $this->type               = $type;
        $this->content            = $content;
        $this->faqId              = $faqId;
        $this->sessionId          = $sessionId;
        $this->isSendAi           = $isSendAi;
        $this->isRecordStatistics = $isRecordStatistics;
    }

    /**
     * @throws Exception
     */
    public function prepareStruct(): array
    {
        // 前置校验
        $session = $this->beforeSendMsg();

        $sessionId = $session->id ?? 0;

        // 敏感词判断
        $sensitive = 0;
        if ($this->type == ChatGroupHistoryModel::TYPE_TEXT) {
            $textContent = new TextContent($this->content);
            $textContent->setServiceCode('chat_detection');
            $verify    = $textContent->verify();
            $sensitive = (int)!($verify['data']['isLegal'] ?? true);
        }

        $db_content = is_array($this->content) ? json_encode($this->content, JSON_UNESCAPED_UNICODE) : $this->content;

        // 插入聊天记录
        $msg = (new ChatGroupHistoryModel)->add($this->clientMsgId, $this->groupId, $this->shopId, $sessionId,
            $this->currentUid, $db_content, $this->type, $sensitive, $this->isSendAi, $this->isRecordStatistics);

        // 发送群消息之后的操作
        $this->afterSendMsg($session, $msg);

        // 消息结构体
        return $msg->getChatStruct();
    }

    private function beforeSendMsg(): ?ChatGroupSessionModel
    {
        // 有主消息 - 用户id判断
        if (in_array($this->type, [
            ChatGroupHistoryModel::TYPE_TEXT,
            ChatGroupHistoryModel::TYPE_IMAGES,
            ChatGroupHistoryModel::TYPE_VIDEOS,
            ChatGroupHistoryModel::TYPE_FAQ
        ])) {
            $isInGroup = ChatGroupUserModel::inGroup($this->groupId, $this->currentUid);
            if (!$isInGroup) {
                BaseService::throwErr("{$this->currentUid}您不在群聊中");
            }
        }

        // session校验

        // tips允许session为空
        if ($this->type == ChatGroupHistoryModel::TYPE_TIPS && !$this->sessionId) {
            return null;
        }

        if ($this->sessionId) {
            $session = ChatGroupSessionModel::find($this->sessionId);
        } else {
            $session = ChatGroupSessionModel::getActiveSession($this->groupId);
        }

        if (!$session) {
            BaseService::throwErr("当前群聊不存在进行中的会话");
        }

        return $session;
    }

    /**
     * 发送群消息之后的操作
     * @param ChatGroupSessionModel|null $session
     * @param ChatGroupHistoryModel $msg
     * @return void
     * @throws Exception
     */
    private function afterSendMsg(?ChatGroupSessionModel $session, ChatGroupHistoryModel $msg): void
    {
        if ($session) {
            // 更新群组最后一次消息时间
            ChatGroupSessionModel::updateColumn(['id' => $session->id], ['lastMsgTime' => time()]);

            // 新增未读消息数量
            (new ChatGroupMessageReadService($this->currentUid))->addUnreadMessage($this->groupId, $session->id);

            // 群组列表 - 置顶消息，需要new
            (new ChatGroupStructService($this->groupId, $this->shopId))->groupListsTopGroup($session)->send();

            // AI/系统回复消息
            ChatGroupPrepareStructService::botRelayChat($session, $this->currentUid, $msg);

            // ai关闭情况下，用户发言，自动呼叫客服
            if (!ChatGroupSessionService::getAiSwitch() && $session->serveIn == ChatGroupSessionModel::SERVE_IN_NO) {

                // 是门店的用户 && 第一次说话
                $inGroup = ChatGroupUserModel::query()
                                             ->where('groupId', $this->groupId)
                                             ->where('userId', $this->currentUid)
                                             ->whereIn('role',
                                                 [ChatGroupUserModel::ROLE_BOSS, ChatGroupUserModel::ROLE_EMPLOYEE])
                                             ->count();

                if ($inGroup) {
                    ChatGroupAiChatService::callServe($this->shopId, $this->groupId);
                }
            }
        }
    }

    /**
     * AI/系统回复消息
     *
     * @param ChatGroupSessionModel|null $session
     * @param int $currentUid
     * @param Model $msg
     * @return void
     * @throws Exception
     */
    private function botRelayChat(?ChatGroupSessionModel $session, int $currentUid, Model $msg)
    {
        // AI开关判断
        if (!ChatGroupSessionService::getAiSwitch()) {
            return;
        }

        Log::info('BOT_AI:botRelayChat', [$session, $currentUid, $msg]);

        // AI 自己聊天不回复
        if ($currentUid == ChatGroupUserModel::KUA_XIAO_FU_USER_ID) {
//            (new ChatGroupStructService($this->groupId, $this->shopId))->aiInThinking($session, 0)->send();
            return;
        }

        // 不发给胡博特的词库
        if ($this->type == ChatGroupHistoryModel::TYPE_TEXT && in_array($this->content,
                ['常见问题', '常见问题清单', '常见问题列表'])) {
            return;
        }

        // 如果用户发送了图片/视频 && AI状态 - 结束对话
        if (in_array($this->type, [ChatGroupHistoryModel::TYPE_VIDEOS, ChatGroupHistoryModel::TYPE_IMAGES]) &&
            self::isRobotIn($session)) {
            ChatGroupAiChatService::aiSendMsg($this->groupId, ChatGroupHistoryModel::TYPE_TEXT,
                '小夸目前无法识别图片，辛苦老板用文字描述下问题~');
            return;
        }

        // 判断是否是常见问题
        // 通过 indexAnswer 获取答案
        $answer = ChatGroupFAQModel::getAnswerByFaqId($this->faqId);

        // 有答案 AI 吐出答案结束
        if (!empty($answer)) {
            ChatGroupAiChatService::sendQuestionAnswer($answer, $this->groupId, false);
            return;
        }

        // ↓ 下面 非文字类型, 以及 非AI自己的话 AI 不做处理
        if ($this->type != ChatGroupHistoryModel::TYPE_TEXT) {
            return;
        }

        // AI 没介入 不回复
        if (!self::isRobotIn($session)) {
            return;
        }

        // 正常 AI 对话
        // 发送 AI 正在思考中
        (new ChatGroupStructService($this->groupId, $this->shopId))->aiInThinking($session, 1)->send();

        // AI 托管聊天
        ChatGroupAiChatService::chatMsgJob($msg->id, $this->groupId, $this->shopId);
    }

    /**
     * AI 是否能介入
     *
     * @param $session
     * @return bool
     */
    private function isRobotIn($session): bool
    {
        return $session->robotIn == ChatGroupSessionModel::ROBOT_IN_YES;
    }
}
